package com.quanyan.financialSystem.service.place.impl;

import com.github.ltsopensource.core.json.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.financialSystem.entity.db.TbBizPlaceBranchPlaceExample;
import com.quanyan.financialSystem.entity.db.TbBizPlaceExample;
import com.quanyan.financialSystem.entity.vo.resp.*;
import com.quanyan.financialSystem.mapper.BranchPlaceMaper;
import com.quanyan.financialSystem.mapper.TbBizPlaceBranchPlaceMapper;
import com.quanyan.financialSystem.mapper.TbBizPlaceMapper;
import com.quanyan.financialSystem.service.place.BranchPlaceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;

/**
 * @author xian-guo
 * @email 498152332@qq.com
 * @date 2016/10/15.
 */
@Service("branchPlaceService")
public class BranchPlaceServiceImpl implements BranchPlaceService {

    private Logger logger = LoggerFactory.getLogger(BranchPlaceServiceImpl.class);

    @Autowired
    private BranchPlaceMaper branchPlaceMaper;

    /**
     * 分管报表
     *
     * @param paramMap
     * @return
     */
    @Override
    public APIResponse<Map<String, Object>> getBranchPlace(Map<String, Object> paramMap) {
        List<RespPlaceProfitReport> respPlaceProfitReportList = this.getBranchDetail(paramMap);
        logger.info("分管报表数据数量---------------------->>>>" + respPlaceProfitReportList.size());
        if (respPlaceProfitReportList.size() > 0) {
            PageObj<List<RespPlaceProfitReport>> result = PageObj.create(branchPlaceMaper.getPlaceCount(paramMap), (int) paramMap.get("pageNum"), (int) paramMap.get("pageSize"), respPlaceProfitReportList);
            Map<String, Object> map = this.getPlaceSumMoney(paramMap);
            map.put("listData", result);
            return APIResponse.returnSuccess(map);
        }
        return APIResponse.returnSuccess();
    }

    /**
     * 分管报表导出数据
     *
     * @param paramMap
     * @return
     */
    @Override
    public APIResponse<Map<String, Object>> getBranchPlaceImport(Map<String, Object> paramMap) {
        List<RespPlaceProfitReport> respPlaceProfitReportList = this.getBranchDetail(paramMap);
        if (respPlaceProfitReportList.size() > 0) {
            Map<String, Object> map = this.getPlaceSumMoney(paramMap);
            map.put("listData", respPlaceProfitReportList);
            map.put("totalCity", branchPlaceMaper.getRespTotalBranchGroupByCityId(paramMap));//按城市合计统计
            return APIResponse.returnSuccess(map);
        }
        return APIResponse.returnFail("查询无数据");
    }

    /**
     * 计算统计金额
     *
     * @param paramMap
     * @return
     */
    private Map<String, Object> getPlaceSumMoney(Map<String, Object> paramMap) {
        Map<String, Object> map = new HashMap<>();
        RespTotalBranchPlace respTotalBranchPlace = branchPlaceMaper.getRespTotalBranchPlace(paramMap);
        BigDecimal b = new BigDecimal(0.00);
        if (null == respTotalBranchPlace) {
            map.put("tatalData", new RespTotalBranchPlace());
            return map;
        }
        if (!(respTotalBranchPlace.getPlaceMoney().compareTo(b) == 0)) {
            respTotalBranchPlace.setRateBusiness(respTotalBranchPlace.getBusinessProfit().multiply(new BigDecimal(100.00)).divide(respTotalBranchPlace.getPlaceMoney(), 2));//毛利/场租成本
            respTotalBranchPlace.setRateIncome(respTotalBranchPlace.getIncomeProfit().multiply(new BigDecimal(100.00)).divide(respTotalBranchPlace.getPlaceMoney(), 2));
        } else {
            respTotalBranchPlace.setRateBusiness(b);
            respTotalBranchPlace.setRateIncome(b);
        }
        map.put("tatalData", respTotalBranchPlace);
        return map;
    }

    /**
     * 计算比例
     *
     * @param paramMap
     * @return
     */
    private List<RespPlaceProfitReport> getBranchDetail(Map<String, Object> paramMap) {
        //会员充值
        List<MemberPayAndSendOrder> memberPayAndSendOrderList = branchPlaceMaper.getMemberPayAndSendOrder(paramMap);
        //会员充值调整金额
//        List<MemberPayAndSenderMoney> memberPayAndSenderMoneyList=branchPlaceMaper.getMemberPaySendMoney(paramMap);
        //销售金额
        List<PlaceSaleMoney> placeSaleMoneyList = branchPlaceMaper.getPlaceSaleMoney(paramMap);
        //鸟蛋优惠
        List<PlaceSaleEggMoney> placeSaleEggMoneyList = branchPlaceMaper.getPlaceSaleEggMoney(paramMap);
        //会员优惠消费部分
        List<DiscountPlaceMoney> discountPlaceMoneyList = branchPlaceMaper.getDiscountPlaceMoney(paramMap);
        //会员优惠退款部分
        List<DiscountPlaceMoney> discountPlaceMoneyListIn = branchPlaceMaper.getDiscountPlaceMoneyIn(paramMap);
        //消费会员赠送金额
        List<DiscountPlaceMoney> consumeGiveAmountList = branchPlaceMaper.getConsumeGiveAmount(paramMap);
        //会员消费新
        List<DiscountNew> discountNewList = branchPlaceMaper.getDiscountPlaceMoneyNew(paramMap);
        //多种经营
        List<PlaceMultManager> placeMultManagerList = branchPlaceMaper.getMultManager(paramMap);
        //场租成本
        List<RentPlaceMoney> rentPlaceMoneyList = branchPlaceMaper.getRentPlacemoney(paramMap);
        List<RespPlaceProfitReport> respPlaceProfitReportList = new ArrayList<>();
        if (memberPayAndSendOrderList.size() > 0) {
            for (int i = 0; i < memberPayAndSendOrderList.size(); i++) {
                RespPlaceProfitReport respPlaceProfitReport = new RespPlaceProfitReport();
                //会员充值，会员充值金额payAmount，调整的金额，计算充值金额要减去这部分payAmount2，赠送金额sendMoney
                MemberPayAndSendOrder memberPayAndSendOrder = memberPayAndSendOrderList.get(i);
                respPlaceProfitReport.setCityId(memberPayAndSendOrder.getCityId());
                respPlaceProfitReport.setPlaceId(memberPayAndSendOrder.getId());
                respPlaceProfitReport.setCityName(memberPayAndSendOrder.getCityName());
                try {
                    respPlaceProfitReport.setStartTime(DateUtils.DATE_FORMAT_yyyy_MM_dd.parse((String) paramMap.get("startTime")));
                    respPlaceProfitReport.setEndTime(DateUtils.DATE_FORMAT_yyyy_MM_dd.parse((String) paramMap.get("endTime")));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                respPlaceProfitReport.setName(memberPayAndSendOrder.getName());
                respPlaceProfitReport.setCode(memberPayAndSendOrder.getCode());
                //MemberPayAndSenderMoney memberPayAndSenderMoney=memberPayAndSenderMoneyList.get(i);//调整金额
                //respPlaceProfitReport.setMemberRecharge(memberPayAndSendOrder.getPayAmount().subtract(memberPayAndSenderMoney.getPayAmount2()).add(memberPayAndSenderMoney.getPayAmount3()));//会员充值  要减去调整金额
                respPlaceProfitReport.setMemberRecharge(memberPayAndSendOrder.getPayAmount());//会员充值
                respPlaceProfitReport.setMemberSendMoney(memberPayAndSendOrder.getSendMoney2().subtract(memberPayAndSendOrder.getSendMoney()));//会员充值赠送的钱 计算赠送金额（sendMoney2-sendMoney）

                //场租成本
                RentPlaceMoney rentPlaceMoney = rentPlaceMoneyList.get(i);
                respPlaceProfitReport.setRentMoney(rentPlaceMoney.getPlacePrice().setScale(2, RoundingMode.HALF_UP));
                //会员优惠消费部分，会员应该支付的debit，会员实际支付的amount，操作前赠送金额beforeGive，操作后赠送金额afterGive
                DiscountPlaceMoney discountPlaceMoney = discountPlaceMoneyList.get(i);
                //会员卡支付消费部分，赠送金额
                BigDecimal discountGiveMoneyOut = discountPlaceMoney.getBeforeGive().subtract(discountPlaceMoney.getAfterGive());
                //会员优惠退款部分，赠送金额
                DiscountPlaceMoney discountPlaceMoneyIn = discountPlaceMoneyListIn.get(i);
                BigDecimal discountGiveMoneyIn = discountPlaceMoneyIn.getBeforeGive().subtract(discountPlaceMoneyIn.getAfterGive());

                //会员消费的赠送金额
                //BigDecimal discountGiveMoney = discountGiveMoneyOut.add(discountGiveMoneyIn);
                BigDecimal discountGiveMoney = consumeGiveAmountList.get(i).getBeforeGive().subtract(consumeGiveAmountList.get(i).getAfterGive());
                //会员卡消费消费部分（排除了会员消费的赠送金额）
                //BigDecimal discountMemOut = discountPlaceMoney.getBeforeAmount().subtract(discountPlaceMoney.getAfterAmount());
                //会员卡消费退款部分 负的
                //BigDecimal discountMemIn = discountPlaceMoneyIn.getBeforeAmount().subtract(discountPlaceMoneyIn.getAfterAmount());

                //会员卡消费（消费部分-退款部分）
                //BigDecimal memberConsumer = discountMemOut.add(discountMemIn);
                BigDecimal memberConsumer = discountNewList.get(i).getBeforeGive();

                //鸟蛋优惠
                PlaceSaleEggMoney placeSaleEggMoney = placeSaleEggMoneyList.get(i);

                //销售金额
                PlaceSaleMoney placeSaleMoney = placeSaleMoneyList.get(i);
                respPlaceProfitReport.setConsumeMemberSendmoney(discountGiveMoney.setScale(2, RoundingMode.HALF_UP));//会员消费赠送金额
                //BigDecimal saleSendMoney = discountPlaceMoney.getDebit().subtract(discountPlaceMoney.getAmount());//会员消费折扣
                //营业额 场地销售金额(排除鸟蛋)+会员充值-鸟蛋   （-会员消费折扣）
                respPlaceProfitReport.setPlaceDoBusiness((placeSaleMoney.getDebit().add(respPlaceProfitReport.getMemberRecharge())
                ).setScale(2, RoundingMode.HALF_UP));               //.subtract(saleSendMoney));//营业额
                //收入金额 场地销售金额(排除鸟蛋)+会员卡消费（排除了会员消费的赠送金额）
                respPlaceProfitReport.setPlaceIncome((placeSaleMoney.getDebit().add(memberConsumer)).setScale(2, RoundingMode.HALF_UP));//收入额

                //多种经营
                PlaceMultManager placeMultManager = placeMultManagerList.get(i);
                respPlaceProfitReport.setPlaceMultIncome(placeMultManager.getDebit().setScale(2, RoundingMode.HALF_UP));
                //毛利（场地营业金额-场租成本）
                respPlaceProfitReport.setPlaceBusinessProfit((respPlaceProfitReport.getPlaceDoBusiness().subtract(respPlaceProfitReport.getRentMoney())).setScale(2, RoundingMode.HALF_UP));
                //毛利（场地收入金额-场租成本）
                respPlaceProfitReport.setPlaceIncomeProfit((respPlaceProfitReport.getPlaceIncome().subtract(respPlaceProfitReport.getRentMoney())).setScale(2, RoundingMode.HALF_UP));
                //投入产出比率（场地营业金额）  毛利/场租成本
                BigDecimal b = new BigDecimal(0.00);
                if (!(respPlaceProfitReport.getRentMoney().compareTo(b) == 0)) {
                    respPlaceProfitReport.setRateBusinessProfit(respPlaceProfitReport.getPlaceBusinessProfit().divide(respPlaceProfitReport.getRentMoney(), 2));
                    //投入产出比率（场地收入金额）  毛利/场租成本
                    respPlaceProfitReport.setRateIncomeProfit(respPlaceProfitReport.getPlaceIncomeProfit().divide(respPlaceProfitReport.getRentMoney(), 2));
                } else {
                    respPlaceProfitReport.setRateBusinessProfit(b.setScale(2, RoundingMode.HALF_UP));
                    //投入产出比率（场地收入金额）  毛利/场租成本
                    respPlaceProfitReport.setRateIncomeProfit(b.setScale(2, RoundingMode.HALF_UP));
                }
                respPlaceProfitReportList.add(respPlaceProfitReport);
            }
        }
        return respPlaceProfitReportList;
    }

    @Autowired
    private TbBizPlaceBranchPlaceMapper bizPlaceBranchPlaceMapper;
    @Autowired
    private TbBizPlaceMapper tbBizPlaceMapper;

    @Override
    @Transactional
    public void sumBranchTask() {
        //查询统计表是否有数据
        TbBizPlaceBranchPlaceExample tbBizPlaceBranchPlaceExample = new TbBizPlaceBranchPlaceExample();
        int countTable = bizPlaceBranchPlaceMapper.countByExample(tbBizPlaceBranchPlaceExample);
        Map<String, Object> paramMap = new HashMap<>();
        //查询场馆总数量
        TbBizPlaceExample tbBizPlaceExample = new TbBizPlaceExample();
        int placeCount = tbBizPlaceMapper.countByExample(tbBizPlaceExample);
        Date date = null;
        if (countTable > 0) {//不是第一次导数据
            List<Map<String, Object>> mapTime = branchPlaceMaper.getDayTime();//取表统计表数据最近时间
            date = (Date) mapTime.get(0).get("day_time");//获取之前统计时间
            logger.info("定时任务每日增量数据--取统计表里面的最新时间----------------->>>>>" + DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
            int countNum1 = DateUtils.dateDiffDay(date, new Date());
            for (int i = 0; i < countNum1 - 1; i++) {
                date = DateUtils.addNDay(date, 1);//t统计后一天到今天的所有数据
                paramMap.put("pageNum", 0);
                paramMap.put("pageSize", placeCount);
                paramMap.put("startTime", DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
                paramMap.put("endTime", DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
                List<RespPlaceProfitReport> respPlaceProfitReportList = this.getBranchDetail(paramMap);
                for (RespPlaceProfitReport respPlaceProfitReport : respPlaceProfitReportList) {//插入时间
                    respPlaceProfitReport.setDayTime(date);
                }
                branchPlaceMaper.insertTotalBranchPlace(respPlaceProfitReportList);
                logger.info("------增量----->>>>>>>>>>" + DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
            }
            return;
        }
        try {
            List<Map<String, Object>> mapTime2 = branchPlaceMaper.getPlaceDayTime();
            date = (Date) mapTime2.get(0).get("create_time");
            String dateFormat = DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date);//第一次导数据，读场馆表时间
            date = DateUtils.DATE_FORMAT_yyyy_MM_dd.parse(dateFormat);
            logger.info("定时任务第一次全量数据--原始数据表最早时间----------------->>>>>" + DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
            int countNum2 = DateUtils.dateDiffDay(date, new Date());
            for (int i = 0; i < countNum2; i++) {
                paramMap.put("pageNum", 0);
                paramMap.put("pageSize", placeCount);
                paramMap.put("startTime", DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
                paramMap.put("endTime", DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
                List<RespPlaceProfitReport> respPlaceProfitReportList = this.getBranchDetail(paramMap);
                for (RespPlaceProfitReport respPlaceProfitReport : respPlaceProfitReportList) {//插入时间
                    respPlaceProfitReport.setDayTime(date);
                }
                branchPlaceMaper.insertTotalBranchPlace(respPlaceProfitReportList);
                logger.info("------全量----->>>>>>>>>>" + DateUtils.DATE_FORMAT_yyyy_MM_dd.format(date));
                date = DateUtils.addNDay(date, 1);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * 会员流水报表
     *
     * @param paramMap
     * @return
     */
    @Override
    public APIResponse<PageObj<List<RespCardMember>>> getCardMemberList(Map<String, Object> paramMap) {
        List<DbCardMember> dbCardMemberList = branchPlaceMaper.getCardMemberList(paramMap);
        logger.info("-------list-----------" + JSON.toJSONString(dbCardMemberList));
        List<RespCardMember> respCardMemberList = new ArrayList<>();
        List<BuyType> buyTypeList = new ArrayList<BuyType>();//查找合同买入类型
        List<DateAndUserType> dateAndUserTypes = new ArrayList<DateAndUserType>();
        for (DbCardMember cardMember : dbCardMemberList) {
            BuyType buyType = new BuyType();
            buyType.setPlaceId(cardMember.getPlaceId());
            buyTypeList.add(buyType);

            DateAndUserType dateAndUserType = new DateAndUserType();
            dateAndUserType.setPlaceId(cardMember.getPlaceId());
            dateAndUserType.setPlaceOrderId(cardMember.getOrderNo());
            dateAndUserTypes.add(dateAndUserType);
        }
        List<BuyType> buyTypes = branchPlaceMaper.getContractByType(buyTypeList);//查看合同买入类型
        //查看对账日期
        List<DateAndUserType> reconciliationDates = branchPlaceMaper.getReconciliationDate(dateAndUserTypes);
        //查看结算日期
        List<DateAndUserType> settleDates = branchPlaceMaper.getSettleDate(dateAndUserTypes);
        //查看销售人
        List<DateAndUserType> createUserNames = branchPlaceMaper.getCreateUserName(dateAndUserTypes);
        for (DbCardMember cardMember : dbCardMemberList) {

            RespCardMember respCardMember = new RespCardMember();
            respCardMember.setCityId(cardMember.getCityId());//城市
            respCardMember.setPlaceName(cardMember.getPlaceName());//场馆名称
            respCardMember.setPlaceCode(cardMember.getPlaceCode());//场馆编号
            respCardMember.setCategoryId(cardMember.getCategoryId());//项目
            if (!buyTypes.isEmpty()) {
                for (BuyType buyType : buyTypes) {
                    //logger.warn("买入类型：===============================" + buyType.getBuyType() + "===" +respCardMember.getPlaceId()+"==="+buyType.getPlaceId()+"===="+ (respCardMember.getPlaceId() == buyType.getPlaceId()));
                    if (cardMember.getPlaceId().equals(buyType.getPlaceId())) {
                        respCardMember.setBuyType(buyType.getBuyType());//买入类型
                        break;
                    }
                }
            }

            respCardMember.setInnerCardNo(cardMember.getInnerCardNo());//会员卡号
            respCardMember.setCardType(cardMember.getCardType());//会员卡类型
            respCardMember.setOrderNo(cardMember.getOrderNo());//订单号
            respCardMember.setPlaceNo(cardMember.getPlaceNo());//交易流水号
            respCardMember.setCreateTime(cardMember.getCreateTime());//支付日期
            //核对日期（对账日期  or  结算日期 ->现金）


            int adminType = cardMember.getAdminPayType();
            if (adminType == 1) {//如果是现金结算，显示结算日期
                if (!settleDates.isEmpty()) {
                    for (DateAndUserType settleDate : settleDates) {
                        if (settleDate.getPlaceOrderId().equals(cardMember.getOrderNo())) {
                            respCardMember.setConCiliAndSettleDate(settleDate.getSettleDate());//结算日期
                            break;
                        }
                    }
                }
            } else {
                //显示对账日期
                if (!reconciliationDates.isEmpty()) {
                    for (DateAndUserType reconciliationDate : reconciliationDates) {
                        if (reconciliationDate.getPlaceOrderId().equals(cardMember.getOrderNo())) {
                            respCardMember.setConCiliAndSettleDate(reconciliationDate.getReconciliationDate());//对账日期
                            break;
                        }
                    }
                }
            }


            respCardMember.setUserName(cardMember.getUserName());//客户名称
            respCardMember.setMobile(cardMember.getMobile());//手机号
            //本金收入 赠送金额收入
            int src = cardMember.getSrc();
            int type = cardMember.getMemType();
            if (src == 1 || src == 3 || src == 5) {//充值，开卡，退款
                respCardMember.setMoneyIn(cardMember.getAmount());//本金
                respCardMember.setSendIn(cardMember.getOpAfterGiveAmount().subtract(cardMember.getOpBeforeGiveAmount()));//赠送金额  操作后-操作前  +
            }
            if (src == 4 && type == 1) {//调整余额收入
                respCardMember.setMoneyIn(cardMember.getAmount());
                respCardMember.setSendIn(cardMember.getOpAfterGiveAmount().subtract(cardMember.getOpBeforeGiveAmount()));//赠送金额
            } else if (src == 4 && type == 0) {
                respCardMember.setMoneyOut(cardMember.getAmount().multiply(new BigDecimal(-1)));
                respCardMember.setSendOut(cardMember.getOpAfterGiveAmount().subtract(cardMember.getOpBeforeGiveAmount()).multiply(new BigDecimal(-1)));//赠送金额
            }
            respCardMember.setCardNum(cardMember.getCardCount());//交易次数
            //本金支出  赠送金额支出
            if (src == 2) {//消费
                respCardMember.setMoneyOut(cardMember.getAmount().multiply(new BigDecimal(-1)));
                respCardMember.setSendOut(cardMember.getOpAfterGiveAmount().subtract(cardMember.getOpBeforeGiveAmount()));//赠送金额
                respCardMember.setCardNum(-cardMember.getCardCount());//交易次数
            }
            if (src == 4 && type == 2) {//调整余额支出
                respCardMember.setMoneyOut(cardMember.getAmount().multiply(new BigDecimal(-1)));
                respCardMember.setSendOut(cardMember.getOpAfterGiveAmount().subtract(cardMember.getOpBeforeGiveAmount()));//赠送金额
                respCardMember.setCardNum(-cardMember.getCardCount());//交易次数
            }
            respCardMember.setPlaceId(cardMember.getPlaceId());
            respCardMember.setMemo(cardMember.getMemo());//备注
            respCardMember.setSrc(cardMember.getSrc());//业务类型
            respCardMember.setPayType(cardMember.getPayType());//支付方式
            respCardMember.setContact(cardMember.getContact());//场馆负责人
            if (!createUserNames.isEmpty()) {
                for (DateAndUserType createUserName : createUserNames) {
                    if (createUserName.getPlaceId() == cardMember.getPlaceId()) {
                        respCardMember.setCreateUserName(createUserName.getCreateUserName());//销售人
                        break;
                    }
                }
            }
            respCardMember.setPlatform(cardMember.getPlatform());//销售渠道
            respCardMemberList.add(respCardMember);
        }


        PageObj<List<RespCardMember>> result = null;
        int totalCount = branchPlaceMaper.getCardMemberListCount(paramMap);
        logger.info("--------------------" + JSON.toJSONString(respCardMemberList));
        if (null == paramMap.get("impor")) {
            result = PageObj.create(totalCount, (int) paramMap.get("pageNum") / (int) paramMap.get("pageSize"), (int) paramMap.get("pageSize"), respCardMemberList);
        } else {//导出excel表格
            result = PageObj.create(totalCount, 0, totalCount, respCardMemberList);
        }
        return APIResponse.returnSuccess(result);
    }

}
